{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color=\"red\">注</font>: 使用 tensorboard 可视化需要安装 tensorflow (TensorBoard依赖于tensorflow库，可以任意安装tensorflow的gpu/cpu版本)\n",
    "\n",
    "```shell\n",
    "pip install tensorflow-cpu\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:24:57.409975Z",
     "start_time": "2025-01-31T15:24:53.596942Z"
    }
   },
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n",
    "\n",
    "seed = 42\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.10.0\n",
      "numpy 1.26.4\n",
      "pandas 2.2.3\n",
      "sklearn 1.6.1\n",
      "torch 2.5.1+cpu\n",
      "cpu\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据准备"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:24:58.957592Z",
     "start_time": "2025-01-31T15:24:57.410977Z"
    }
   },
   "source": [
    "from torchvision import datasets\n",
    "from torchvision.transforms import ToTensor\n",
    "from torch.utils.data import random_split\n",
    "\n",
    "# fashion_mnist图像分类数据集\n",
    "train_ds = datasets.FashionMNIST(\n",
    "    root=\"data\",\n",
    "    train=True,\n",
    "    download=True,\n",
    "    transform=ToTensor()\n",
    ")\n",
    "\n",
    "test_ds = datasets.FashionMNIST(\n",
    "    root=\"data\",\n",
    "    train=False,\n",
    "    download=True,\n",
    "    transform=ToTensor()\n",
    ")\n",
    "\n",
    "# torchvision 数据集里没有提供训练集和验证集的划分\n",
    "# 这里用 random_split 按照 11 : 1 的比例来划分数据集\n",
    "train_ds, val_ds = random_split(train_ds, [55000, 5000], torch.Generator().manual_seed(seed))"
   ],
   "outputs": [],
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:24:58.964267Z",
     "start_time": "2025-01-31T15:24:58.958627Z"
    }
   },
   "source": [
    "from torchvision.transforms import Normalize\n",
    "\n",
    "# 遍历train_ds得到每张图片，计算每个通道的均值和方差\n",
    "def cal_mean_std(ds):\n",
    "    mean = 0.\n",
    "    std = 0.\n",
    "    for img, _ in ds:\n",
    "        mean += img.mean(dim=(1, 2))\n",
    "        std += img.std(dim=(1, 2))\n",
    "    mean /= len(ds)\n",
    "    std /= len(ds)\n",
    "    return mean, std\n",
    "\n",
    "\n",
    "# print(cal_mean_std(train_ds))\n",
    "# 0.2860， 0.3205\n",
    "transforms = nn.Sequential(\n",
    "    Normalize([0.2856], [0.3202])\n",
    ")"
   ],
   "outputs": [],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:24:58.975212Z",
     "start_time": "2025-01-31T15:24:58.965265Z"
    }
   },
   "source": [
    "from torch.utils.data.dataloader import DataLoader\n",
    "\n",
    "batch_size = 32\n",
    "# 从数据集到dataloader\n",
    "train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True, num_workers=4)\n",
    "val_loader = DataLoader(val_ds, batch_size=batch_size, shuffle=False, num_workers=4)\n",
    "test_loader = DataLoader(test_ds, batch_size=batch_size, shuffle=False, num_workers=4)"
   ],
   "outputs": [],
   "execution_count": 4
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义模型\n",
    "\n",
    "使用深度可分离的卷积\n",
    "\n",
    "pytorch需要自行实现"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:24:58.986225Z",
     "start_time": "2025-01-31T15:24:58.977207Z"
    }
   },
   "source": [
    "# 定义深度可分离卷积层，torch没有实现，tf有实现\n",
    "class DepthWiseConv2d(nn.Module):\n",
    "    def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, bias=True):\n",
    "        super(DepthWiseConv2d, self).__init__() #这里写为super().__init__()，等价的\n",
    "        self.depthwise_conv = nn.Conv2d(in_channels, in_channels, kernel_size, stride, padding, groups=in_channels, bias=False) #groups参数表示一个卷积核的每个通道分别进行运算\n",
    "        self.pointwise_conv = nn.Conv2d(in_channels, out_channels, 1, 1, 0, bias=bias)\n",
    "    \n",
    "    def forward(self, x):\n",
    "        x = self.depthwise_conv(x)\n",
    "        x = self.pointwise_conv(x)\n",
    "        return x"
   ],
   "outputs": [],
   "execution_count": 5
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:24:59.002150Z",
     "start_time": "2025-01-31T15:24:58.986225Z"
    }
   },
   "source": [
    "\n",
    "class CNN(nn.Module):\n",
    "    def __init__(self, activation=\"relu\"):\n",
    "        super(CNN, self).__init__()\n",
    "        self.activation = F.relu if activation == \"relu\" else F.selu\n",
    "        self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=\"same\")\n",
    "        self.conv2 = DepthWiseConv2d(in_channels=32, out_channels=32, kernel_size=3, padding=\"same\")\n",
    "        self.pool = nn.MaxPool2d(2, 2)\n",
    "        self.conv3 = DepthWiseConv2d(in_channels=32, out_channels=64, kernel_size=3, padding=\"same\")\n",
    "        self.conv4 = DepthWiseConv2d(in_channels=64, out_channels=64, kernel_size=3, padding=\"same\")\n",
    "        self.conv5 = DepthWiseConv2d(in_channels=64, out_channels=128, kernel_size=3, padding=\"same\")\n",
    "        self.conv6 = DepthWiseConv2d(in_channels=128, out_channels=128, kernel_size=3, padding=\"same\")\n",
    "        self.flatten = nn.Flatten()\n",
    "        # input shape is (28, 28, 1) so the fc1 layer in_features is 128 * 3 * 3\n",
    "        self.fc1 = nn.Linear(128 * 3 * 3, 128)\n",
    "        self.fc2 = nn.Linear(128, 10)\n",
    "        \n",
    "        self.init_weights()\n",
    "        \n",
    "    def init_weights(self):\n",
    "        \"\"\"使用 xavier 均匀分布来初始化全连接层、卷积层的权重 W\"\"\"\n",
    "        for m in self.modules():\n",
    "            if isinstance(m, (nn.Linear, nn.Conv2d)):\n",
    "                nn.init.xavier_uniform_(m.weight)\n",
    "                if m.bias is not None:\n",
    "                    nn.init.zeros_(m.bias)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        act = self.activation\n",
    "        #x -->(batch_size, 1, 28, 28)\n",
    "        x = self.pool(act(self.conv2(act(self.conv1(x)))))  # (batch_size, 32, 14, 14)\n",
    "        x = self.pool(act(self.conv4(act(self.conv3(x)))))  # (batch_size, 64, 7, 7)\n",
    "        x = self.pool(act(self.conv6(act(self.conv5(x)))))  # (batch_size, 128, 3, 3)\n",
    "        x = self.flatten(x) # (batch_size, 128 * 3 * 3)\n",
    "        x = act(self.fc1(x)) # (batch_size, 128)\n",
    "        x = self.fc2(x) # (batch_size, 10)\n",
    "        return x\n",
    "    \n",
    "\n",
    "for idx, (key, value) in enumerate(CNN().named_parameters()):\n",
    "    print(f\"{key}\\tparamerters num: {np.prod(value.shape)}\")\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "conv1.weight\tparamerters num: 288\n",
      "conv1.bias\tparamerters num: 32\n",
      "conv2.depthwise_conv.weight\tparamerters num: 288\n",
      "conv2.pointwise_conv.weight\tparamerters num: 1024\n",
      "conv2.pointwise_conv.bias\tparamerters num: 32\n",
      "conv3.depthwise_conv.weight\tparamerters num: 288\n",
      "conv3.pointwise_conv.weight\tparamerters num: 2048\n",
      "conv3.pointwise_conv.bias\tparamerters num: 64\n",
      "conv4.depthwise_conv.weight\tparamerters num: 576\n",
      "conv4.pointwise_conv.weight\tparamerters num: 4096\n",
      "conv4.pointwise_conv.bias\tparamerters num: 64\n",
      "conv5.depthwise_conv.weight\tparamerters num: 576\n",
      "conv5.pointwise_conv.weight\tparamerters num: 8192\n",
      "conv5.pointwise_conv.bias\tparamerters num: 128\n",
      "conv6.depthwise_conv.weight\tparamerters num: 1152\n",
      "conv6.pointwise_conv.weight\tparamerters num: 16384\n",
      "conv6.pointwise_conv.bias\tparamerters num: 128\n",
      "fc1.weight\tparamerters num: 147456\n",
      "fc1.bias\tparamerters num: 128\n",
      "fc2.weight\tparamerters num: 1280\n",
      "fc2.bias\tparamerters num: 10\n"
     ]
    }
   ],
   "execution_count": 6
  },
  {
   "cell_type": "code",
   "source": [
    "# 总权重数 = 288 + 288 + 1024 + 2048 + 576 + 8192 + 1152 + 16384 + 147456 + 1280 = 186624\n",
    "# 总偏置数 = 32 + 32 + 64 + 64 + 128 + 128 + 10 = 438\n",
    "#\n",
    "# 整个网络的总参数数为：\n",
    "#\n",
    "# 总参数数 = 总权重数 + 总偏置数 = 186624 + 438 = 187062"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-01-31T15:24:59.006498Z",
     "start_time": "2025-01-31T15:24:59.003148Z"
    }
   },
   "outputs": [],
   "execution_count": 7
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练\n",
    "\n",
    "pytorch的训练需要自行实现，包括\n",
    "1. 定义损失函数\n",
    "2. 定义优化器\n",
    "3. 定义训练步\n",
    "4. 训练"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:24:59.071874Z",
     "start_time": "2025-01-31T15:24:59.007496Z"
    }
   },
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    pred_list = []\n",
    "    label_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        \n",
    "        preds = logits.argmax(axis=-1)    # 验证集预测\n",
    "        pred_list.extend(preds.cpu().numpy().tolist())\n",
    "        label_list.extend(labels.cpu().numpy().tolist())\n",
    "        \n",
    "    acc = accuracy_score(label_list, pred_list)\n",
    "    return np.mean(loss_list), acc"
   ],
   "outputs": [],
   "execution_count": 8
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### TensorBoard 可视化\n",
    "\n",
    "\n",
    "训练过程中可以使用如下命令启动tensorboard服务。\n",
    "\n",
    "```shell\n",
    "tensorboard \\\n",
    "    --logdir=runs \\     # log 存放路径\n",
    "    --host 0.0.0.0 \\    # ip\n",
    "    --port 8848         # 端口\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:25:02.484474Z",
     "start_time": "2025-01-31T15:24:59.072872Z"
    }
   },
   "source": [
    "from torch.utils.tensorboard import SummaryWriter\n",
    "\n",
    "\n",
    "class TensorBoardCallback:\n",
    "    def __init__(self, log_dir, flush_secs=10):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            log_dir (str): dir to write log.\n",
    "            flush_secs (int, optional): write to dsk each flush_secs seconds. Defaults to 10.\n",
    "        \"\"\"\n",
    "        self.writer = SummaryWriter(log_dir=log_dir, flush_secs=flush_secs)\n",
    "\n",
    "    def draw_model(self, model, input_shape):\n",
    "        self.writer.add_graph(model, input_to_model=torch.randn(input_shape))\n",
    "        \n",
    "    def add_loss_scalars(self, step, loss, val_loss):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/loss\", \n",
    "            tag_scalar_dict={\"loss\": loss, \"val_loss\": val_loss},\n",
    "            global_step=step,\n",
    "            )\n",
    "        \n",
    "    def add_acc_scalars(self, step, acc, val_acc):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/accuracy\",\n",
    "            tag_scalar_dict={\"accuracy\": acc, \"val_accuracy\": val_acc},\n",
    "            global_step=step,\n",
    "        )\n",
    "        \n",
    "    def add_lr_scalars(self, step, learning_rate):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/learning_rate\",\n",
    "            tag_scalar_dict={\"learning_rate\": learning_rate},\n",
    "            global_step=step,\n",
    "            \n",
    "        )\n",
    "    \n",
    "    def __call__(self, step, **kwargs):\n",
    "        # add loss\n",
    "        loss = kwargs.pop(\"loss\", None)\n",
    "        val_loss = kwargs.pop(\"val_loss\", None)\n",
    "        if loss is not None and val_loss is not None:\n",
    "            self.add_loss_scalars(step, loss, val_loss)\n",
    "        # add acc\n",
    "        acc = kwargs.pop(\"acc\", None)\n",
    "        val_acc = kwargs.pop(\"val_acc\", None)\n",
    "        if acc is not None and val_acc is not None:\n",
    "            self.add_acc_scalars(step, acc, val_acc)\n",
    "        # add lr\n",
    "        learning_rate = kwargs.pop(\"lr\", None)\n",
    "        if learning_rate is not None:\n",
    "            self.add_lr_scalars(step, learning_rate)"
   ],
   "outputs": [],
   "execution_count": 9
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Save Best\n"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:25:02.489320Z",
     "start_time": "2025-01-31T15:25:02.484474Z"
    }
   },
   "source": [
    "class SaveCheckpointsCallback:\n",
    "    def __init__(self, save_dir, save_step=5000, save_best_only=True):\n",
    "        \"\"\"\n",
    "        Save checkpoints each save_epoch epoch. \n",
    "        We save checkpoint by epoch in this implementation.\n",
    "        Usually, training scripts with pytorch evaluating model and save checkpoint by step.\n",
    "\n",
    "        Args:\n",
    "            save_dir (str): dir to save checkpoint\n",
    "            save_epoch (int, optional): the frequency to save checkpoint. Defaults to 1.\n",
    "            save_best_only (bool, optional): If True, only save the best model or save each model at every epoch.\n",
    "        \"\"\"\n",
    "        self.save_dir = save_dir\n",
    "        self.save_step = save_step\n",
    "        self.save_best_only = save_best_only\n",
    "        self.best_metrics = -1\n",
    "        \n",
    "        # mkdir\n",
    "        if not os.path.exists(self.save_dir):\n",
    "            os.mkdir(self.save_dir)\n",
    "        \n",
    "    def __call__(self, step, state_dict, metric=None):\n",
    "        if step % self.save_step > 0:\n",
    "            return\n",
    "        \n",
    "        if self.save_best_only:\n",
    "            assert metric is not None\n",
    "            if metric >= self.best_metrics:\n",
    "                # save checkpoints\n",
    "                torch.save(state_dict, os.path.join(self.save_dir, \"best.ckpt\"))\n",
    "                # update best metrics\n",
    "                self.best_metrics = metric\n",
    "        else:\n",
    "            torch.save(state_dict, os.path.join(self.save_dir, f\"{step}.ckpt\"))"
   ],
   "outputs": [],
   "execution_count": 10
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Early Stop"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:25:02.499599Z",
     "start_time": "2025-01-31T15:25:02.489320Z"
    }
   },
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = -1\n",
    "        self.counter = 0\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience"
   ],
   "outputs": [],
   "execution_count": 11
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:42:54.530893Z",
     "start_time": "2025-01-31T15:25:16.088467Z"
    }
   },
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    tensorboard_callback=None,\n",
    "    save_ckpt_callback=None,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for datas, labels in train_loader:\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas)\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    "                preds = logits.argmax(axis=-1)\n",
    "            \n",
    "                acc = accuracy_score(labels.cpu().numpy(), preds.cpu().numpy())    \n",
    "                loss = loss.cpu().item()\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"acc\": acc, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss, val_acc = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"acc\": val_acc, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "                    \n",
    "                    # 1. 使用 tensorboard 可视化\n",
    "                    if tensorboard_callback is not None:\n",
    "                        tensorboard_callback(\n",
    "                            global_step, \n",
    "                            loss=loss, val_loss=val_loss,\n",
    "                            acc=acc, val_acc=val_acc,\n",
    "                            lr=optimizer.param_groups[0][\"lr\"],\n",
    "                            )\n",
    "                    \n",
    "                    # 2. 保存模型权重 save model checkpoint\n",
    "                    if save_ckpt_callback is not None:\n",
    "                        save_ckpt_callback(global_step, model.state_dict(), metric=val_acc)\n",
    "\n",
    "                    # 3. 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(val_acc)\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 20\n",
    "\n",
    "activation = \"selu\"\n",
    "model = CNN(activation)\n",
    "\n",
    "# 1. 定义损失函数 采用交叉熵损失\n",
    "loss_fct = nn.CrossEntropyLoss()\n",
    "# 2. 定义优化器 采用SGD\n",
    "# Optimizers specified in the torch.optim package\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n",
    "\n",
    "# 1. tensorboard 可视化\n",
    "if not os.path.exists(\"runs\"):\n",
    "    os.mkdir(\"runs\")\n",
    "tensorboard_callback = TensorBoardCallback(f\"runs/dsc-{activation}\")\n",
    "tensorboard_callback.draw_model(model, [1, 1, 28, 28])\n",
    "# 2. save best\n",
    "if not os.path.exists(\"checkpoints\"):\n",
    "    os.makedirs(\"checkpoints\")\n",
    "save_ckpt_callback = SaveCheckpointsCallback(f\"checkpoints/dsc-{activation}\", save_step=len(train_loader), save_best_only=True)\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    tensorboard_callback=None,\n",
    "    save_ckpt_callback=save_ckpt_callback,\n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_loader)\n",
    "    )"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  0%|          | 0/34380 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "e9a1f5929e99432eb057ef4442f17055"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 12
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:47:19.377797Z",
     "start_time": "2025-01-31T15:47:19.132296Z"
    }
   },
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    fig_num = len(train_df.columns)\n",
    "    fig, axs = plt.subplots(1, fig_num, figsize=(5 * fig_num, 5))\n",
    "    for idx, item in enumerate(train_df.columns):    \n",
    "        axs[idx].plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        axs[idx].plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        axs[idx].grid()\n",
    "        axs[idx].legend()\n",
    "        axs[idx].set_xticks(range(0, train_df.index[-1], 5000))\n",
    "        axs[idx].set_xticklabels(map(lambda x: f\"{int(x/1000)}k\", range(0, train_df.index[-1], 5000)))\n",
    "        axs[idx].set_xlabel(\"step\")\n",
    "    \n",
    "    plt.show()\n",
    "\n",
    "plot_learning_curves(record, sample_step=500)  #横坐标是 steps"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1000x500 with 2 Axes>"
      ],
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 13
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 评估"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-31T15:49:56.072869Z",
     "start_time": "2025-01-31T15:49:45.023606Z"
    }
   },
   "source": [
    "# dataload for evaluating\n",
    "\n",
    "# load checkpoints\n",
    "model.load_state_dict(torch.load(f\"checkpoints/dsc-{activation}/best.ckpt\",weights_only = True,map_location=\"cpu\"))\n",
    "\n",
    "model.eval()\n",
    "loss, acc = evaluating(model, test_loader, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\\naccuracy: {acc:.4f}\")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.3448\n",
      "accuracy: 0.8758\n"
     ]
    }
   ],
   "execution_count": 16
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": ""
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
